<?php
namespace PsiFramework\Applications\DefaultApp\Classes\DAO;

import("Classes.DAO.AbstractDAO");
import("Applications.DefaultApp.Classes.Model.User");
import("Classes.Util.Object.Date");

use \PsiFramework\Classes\DAO\AbstractDAO;
use \PsiFramework\Classes\Util\Parameters\ObjectParameters;
use \PsiFramework\Classes\Util\Object\Date;
use \PsiFramework\Classes\Util\Database\Builder\QueryBuilder;
use \PsiFramework\Classes\Util\Database\Query\SqlColumn;
use \PsiFramework\Classes\Util\Database\Query\SqlFunction;
use \PsiFramework\Classes\Util\Database\Query\SqlOperation;
use \PsiFramework\Classes\Util\Database\Query\SqlTable;
use \PsiFramework\Classes\Util\Database\Query\SqlValue;
use \PsiFramework\Applications\DefaultApp\Classes\Model\User;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The UserDAO is the Data Access Object for the class User
 *
 * @package DAO
 */
class UserDAO extends AbstractDAO
{

    protected static $_singleton = null;

    /**
     * Retrieve the user who corresponds to the specified login and password
     *
     * @param     string    $login       the user login
     * @param     string    $password    the user password
     * @return    User      the retrieved user
     */
    public function retrieveByLoginPassword(
        /*string*/ $login,
        /*string*/ $password
    )
    {

        $queryBuilder = new QueryBuilder();
        $queryBuilder->createSelectQuery();

        $table = new SqlTable("users", "psiframework");
        $queryBuilder->setTable($table);

        $columnlogin = new SqlColumn("user_login", $table);
        $columnEmail = new SqlColumn("user_email", $table);
        $columnPassword = new SqlColumn("user_password", $table);

        $and = new SqlOperation(SqlOperation::$and);

        $or = new SqlOperation(SqlOperation::$or);

        $equalLogin = new SqlOperation(SqlOperation::$equal);
        $equalLogin->addParameter($columnlogin);
        $equalLogin->addParameter(new SqlValue($login));

        $equalEmail = new SqlOperation(SqlOperation::$equal);
        $equalEmail->addParameter($columnEmail);
        $equalEmail->addParameter(new SqlValue($login));

        $or->addParameter($equalLogin);
        $or->addParameter($equalEmail);

        $equalPassword = new SqlOperation(SqlOperation::$equal);
        $equalPassword->addParameter($columnPassword);
        $equalPassword->addParameter(new SqlValue($password));

        $and->addParameter($or);
        $and->addParameter($equalPassword);

        $queryBuilder->addWhereClause($and);

        $query = $queryBuilder->buildQuery();

        $result = $this->_database->executeQuery($query);
        $user = null ;
        if ($result) {
            $obj = $this->_database->getNextResult($result);
            if ($obj) {
                $user = self::getObjectFromSqlObject($obj);
            }
        }
        return $user;
    }

    protected function retrieveByValue(
        /*string*/ $colName,
        /*string*/ $value,
        /*int*/    $userId
    )
    {

        $queryBuilder = new QueryBuilder();
        $queryBuilder->createSelectQuery();

        $table = new SqlTable("users", "psiframework");
        $queryBuilder->setTable($table);

        $columnValue = new SqlColumn($colName, $table);
        $columnId = new SqlColumn("user_id", $table);

        $and = new SqlOperation(SqlOperation::$and);

        $equalValue = new SqlOperation(SqlOperation::$equal);
        $equalValue->addParameter($columnValue);
        $equalValue->addParameter(new SqlValue($value));
        $and->addParameter($equalValue);

        if (!isNullOrEmptyString($userId)) {
            $equalId = new SqlOperation(SqlOperation::$different);
            $equalId->addParameter($columnId);
            $equalId->addParameter(new SqlValue($userId));

            $and->addParameter($equalId);
        }

        $queryBuilder->addWhereClause($and);

        $query = $queryBuilder->buildQuery();

        $result = $this->_database->executeQuery($query);
        $user = null ;
        if ($result) {
            $obj = $this->_database->getNextResult($result);
            if ($obj) {
                $user = self::getObjectFromSqlObject($obj);
            }
        }

        return $user;
    }

    /**
     * Retrieve the user who corresponds to the specified login and password
     *
     * @param     string    $login        the user login
     * @param     int        $userId        the user id
     * @return     User    the retrieved user
     */
    public function retrieveByLogin(/*string*/ $login, /*int*/ $userId)
    {
        return $this->retrieveByValue("user_login", $login, $userId);
    }

    /**
     * Retrieve the user who corresponds to the specified login and password
     *
     * @param     string    $email        the user email
     * @param     int        $userId        the user id
     * @return     User    the retrieved user
     */
    public function retrieveByEmail(/*string*/ $email, /*int*/ $userId)
    {
        return $this->retrieveByValue("user_email", $email, $userId);
    }

    /**
     * Function to be called instead of the constructor.
     *
     * @return UserDAO    instance
     */
    public static function getInstance(ObjectParameters $objectParameters)
    {

        if (self::$_singleton==null) {
            self::$_singleton = new UserDAO($objectParameters);
        }

        return self::$_singleton;
    }

}
